package com.scf.common.aop;

import com.scf.common.exception.BusinessException;
import com.scf.common.vo.RestResult;
import com.scf.common.vo.RestResultFactory;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Service;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.validation.ObjectError;

import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;
import java.util.List;

/**
 * @author sunchuanfu
 */
@Service
@Slf4j
@Aspect
public class ControllerAspect {

    /**
     * 定义切面
     */
    @Pointcut(value = "execution(* com.scf.controller..*(..))")
    public void controllerPointCut() {
    }

    @Around(value = "controllerPointCut()")
    public RestResult<Object> around(ProceedingJoinPoint pjp) {
        try {
            // 拦截到方法参数
            Object[] args = pjp.getArgs();
            if (args != null) {
                for (Object arg : args) {
                    if (arg instanceof BindingResult) {
                        BindingResult bindingResult = (BindingResult) arg;
                        if (bindingResult.hasErrors()) {
                            List<ObjectError> errors = bindingResult.getAllErrors();
                            StringBuilder sb = new StringBuilder();
                            for (ObjectError error : errors) {
                                if (error instanceof FieldError) {
                                    FieldError fe = (FieldError) error;
                                    sb.append(fe.getField()).append(fe.getDefaultMessage()).append(";");
                                } else {
                                    sb.append(error.getDefaultMessage()).append(";");
                                }
                            }
                            return RestResultFactory.createErrorResult(sb.toString());
                        }
                    }
                }
            }
            // 执行被代理方法
            Object objReturn = pjp.proceed();
            // 返回结果
            return RestResultFactory.createSuccessResult(objReturn);
        } catch (BusinessException e) {
            log.error("业务异常", e);
            return RestResultFactory.createErrorResult(e.getMessage());
        } catch (ConstraintViolationException e) {
            StringBuilder sb = new StringBuilder();
            for (ConstraintViolation<?> s : e.getConstraintViolations()) {
                sb.append(s.getMessage());
            }
            log.error("传参异常", e);
            return RestResultFactory.createErrorResult(sb.toString());
        } catch (Throwable e) {
            log.error("系统异常", e);
            return RestResultFactory.createErrorResult("系统异常");
        }
    }

}
